package com.cacho.s2b.lesson.learn;

import com.cacho.s2b.lesson.utils.EncryptHelper;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.gson.Gson;
import com.nimbusds.jose.JWSSigner;
import com.nimbusds.jose.JWSObject;
import com.nimbusds.jose.JWSHeader;
import com.nimbusds.jose.JWSAlgorithm;
import com.nimbusds.jose.JWSVerifier;
import com.nimbusds.jose.JOSEObjectType;
import com.nimbusds.jose.Payload;
import com.nimbusds.jose.crypto.RSASSASigner;
import com.nimbusds.jose.crypto.factories.DefaultJWSVerifierFactory;
import com.nimbusds.jwt.JWTClaimsSet;
import com.nimbusds.jwt.SignedJWT;

import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * @Description com.nimbusds >nimbus-jose-jwt
 * @Author LingWei
 * @date 2025/04/12
 **/
public class LearnNimbusJoseJwt {
    public final static String PRIVATE_KEY = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCWXsFfnioGbXt0VUqiIZXGoe/Iso2msDO+UCngunf0apGnvuvO5QmEEgv6aAp/Mld4F7oG7ICTTlPDhh9yPVLfQdFGzQDhzl8tx4Mqt0tf0TJWnE7g9vh7dlrx51D9HOhx3Yt5IpMW6JkdneaMkHPFvA5SxCOBZqPbvwYYEx0c0kLjmdlONLDOBZ7ko4vlWRZ2c9ljFo9EfQIZPmnV7Ujt5p4n/M1VGev5AmuHJdyiui34wHjCqpWrM8k2fAKPuW8WUHnnDxbdU5fDSe9YLgs7SbrViA6FfzXl0E1xnZGckDeScTdHQvrPGHexYijAPTOasHUw1BSlvJvSbOOLqLVjAgMBAAECggEAB8iq6Oi2kzOapuh9XwwvBSO/1ltL0tufKhRbPptYd0oG9TCAY2rexbvra9Bz7qar+Xb89bvLYhS1aFMqkI7VGeJ901TsXUQCEEwaIZ1wZOre2LXprWKLdVSom4oWWqvi6nYF8MTV6WMr/ej9FLyriYpVEXq+vcWS6N6oEZn3sVSqt7CtXG6kvKocfKyWe2guEXJWzPpb3SylMwthEovhlXUXNn7DVswp10RTmv4igp4CRzWh8lsYLqY5s+Y/7LW9j3IjJq9FyTfl0zg2M1yqBftRhqOo5QUL3CpgZtLMKg+W3JrCSyP1y6NkApXuNgctrAHPpL3L2+vs7de2f3YwaQKBgQC9r14LbC8RbYR1hnOS6/+EHdReMdBqghtJId+bIu0rQ3DqvhgubgTNXWMjpYF6uOsxNWjtfOxTd3qmnLlCuyGK3Ir4lFVmjcQ6BOI7TDE2vEQEnbXckt2P/kk/xnYcoPG8ocxf2F1rMNCwswd40PJF/LbM3P9FDbO/QaFLkiFySQKBgQDK8L34SJKR9aBHE+201WF1jGVboEOz+yCcDPI1+P5e1pdOQJSIJZBMau/+2WYW7JlhaTYHGqbwO8RG2ZqeGkTJ/TMRDR5kn9+6edisfsX6l79hx+Ym4RdgKbBJm14qs9/pD2KOnw8lBdYCYgEhgYsq89nDmj2UkTjAqaYaDjpqSwKBgHmKid8V1d775rkLirikoVf9aRtmHd5xOZyVqNqV+ZQUJaE0ZvgxJMCWSzUHEr0ZChLA31f1CNS+pQdnOsoIcAizIhT/ru0Ef6yRfohyXMJuxcKTb3lDXdarIDJOL1ZOxjaREgyD7fAGGmJuhKYkdGjl8he4r5SGoBs3qWtr2iSJAoGAQwW296SgI2xHfrHqM2q1QSkY4GXRdkNdxavQ4lpVR+T/G2zgoQYm3dYDZNtPiAqjrTQeD8KRl41liTCci9KJHVxt3RfEDd9u+Br9oBpOMDClmBl4vSZhnfSmr+iL9PZq4IGgPxHw4n1G7IqJbRNnbswSAzORWtuLLrXYkYpZaHkCgYEAjhV9YWpQkTiTDvvPPDXqpRwVFV7uoRiPwptmdpe6l6lFkxi+E6lm4zk46oLC8QMFEEWI2IvyZvahC1y3BqDhkM+qRX4DecpA1HgA6GLZTAZ3qk+Rc7+8Y+gcot4y/rW+7jrayreWKptkvmnyNGdMvXMCEXcRSBBveSfxg3Lbe/0=";
    public final static String PUBLIC_KEY = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAll7BX54qBm17dFVKoiGVxqHvyLKNprAzvlAp4Lp39GqRp77rzuUJhBIL+mgKfzJXeBe6BuyAk05Tw4Yfcj1S30HRRs0A4c5fLceDKrdLX9EyVpxO4Pb4e3Za8edQ/Rzocd2LeSKTFuiZHZ3mjJBzxbwOUsQjgWaj278GGBMdHNJC45nZTjSwzgWe5KOL5VkWdnPZYxaPRH0CGT5p1e1I7eaeJ/zNVRnr+QJrhyXcorot+MB4wqqVqzPJNnwCj7lvFlB55w8W3VOXw0nvWC4LO0m61YgOhX815dBNcZ2RnJA3knE3R0L6zxh3sWIowD0zmrB1MNQUpbyb0mzji6i1YwIDAQAB";

    public static void main(String[] args) {
        String jwsSignature = "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9..ORXMl3tx573t1TTB7L8cpNRxVQS4viRPavCQYEGvl2CPPWFC2DCxtyv5iUIy9OvySEv-Z4H5kdW5pAi6sqDNDwus-uz2O2GWhhXJeFbEwCwDynWUU7zLzj5lX2BytOkpCH8c_mjOyHk_xCMC9gcPuj7dIMKE6mslc_1pxKJckaaDDRWLGdiys24yHpeg37h2DijPS0L9wjjdpggRS-qB_iuh3SouS62xEnRnsVVIDtUGow1S2Eq-dMJMjsc5Gu1byZ3YzJ-F9tCxT5zALwtzlSiHG31NsTlfx1gb76BYc7GKBzM7R7bDiqVV5JrXKafZ839J0r8SCswF0FsPKmo3HA";
        // System.out.println("生成的JWS：" + generateJws());
        // System.out.println("验证JWS结果：" + jwsVerified(jwsSignature));
        generateJwt();
    }

    public static String generateJwt() {
        Map<String, String> payload = new HashMap<>();
        payload.put("scope", "payments");
        payload.put("payload", "{\"sessionId\":\"test\"}");
        PrivateKey privateKey = new EncryptHelper().StringToPrivateKey(PRIVATE_KEY);
        JWTClaimsSet.Builder builder = new JWTClaimsSet.Builder();
        for (Map.Entry<String, String> entry : payload.entrySet()) {
            try {
                Map obj = new Gson().fromJson(entry.getValue(), Map.class);
                builder.claim(entry.getKey(), obj);
            } catch (Exception e) {
                builder.claim(entry.getKey(), entry.getValue());
            }
        }
        System.out.println(builder.getClaims());
        JWTClaimsSet claims = builder.issuer("CACHO").issueTime(new Date(System.currentTimeMillis())).
                expirationTime(new Date(System.currentTimeMillis() + 30000)).build(); // 30000毫秒=30秒
        // 创建 JWS 头部
        JWSHeader header = new JWSHeader.Builder(JWSAlgorithm.RS256).
                type(JOSEObjectType.JWT).build();
        // 创建签名的JWT
        SignedJWT signedJWT = new SignedJWT(header, claims);
        RSASSASigner signer = new RSASSASigner(privateKey);
        try {
            signedJWT.sign(signer);
        } catch (Exception e) {
            e.printStackTrace();
        }
        // 将JWT转换为字符串形式
        String jwtString = signedJWT.serialize();
        System.out.println("RS256 JWT：" + jwtString);
        return jwtString;
    }

    public static String generateJws() {
        try {
            JWSSigner signer = new RSASSASigner(new EncryptHelper().StringToPrivateKey(PRIVATE_KEY));
            String payload = Files.readString(Paths.get(Objects.requireNonNull(LearnNimbusJoseJwt.class.getClassLoader().
                    getResource("jwsSample.json")).toURI()));
            JWSObject jwsObject = new JWSObject(new JWSHeader.Builder(JWSAlgorithm.RS256).
                    type(JOSEObjectType.JWT).build(), new Payload(payload));
            jwsObject.sign(signer);
            String[] splitString = jwsObject.serialize().split("\\.");
            System.out.println("JWS完整数据：" + jwsObject.serialize());
            return splitString[0] + ".." + splitString[2];
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }
    }

    public static boolean jwsVerified(String jwsSignature) {
        PublicKey publicKey = new EncryptHelper().StringToPublicKey(PUBLIC_KEY);
        try {
            String payload = Files.readString(Paths.get(Objects.requireNonNull(LearnNimbusJoseJwt.class.getClassLoader().
                    getResource("jwsSample.json")).toURI()));
            JWSObject jwsObject = JWSObject.parse(jwsSignature, new Payload(payload));
            DefaultJWSVerifierFactory factory = new DefaultJWSVerifierFactory();
            JWSVerifier verifier = factory.createJWSVerifier(jwsObject.getHeader(), publicKey);
            boolean isValidSignature = jwsObject.verify(verifier);
            return isValidSignature;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
}
